/*
 *  This file is part of Cha++ers.
 *
 *  Cha++ers is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Cha++ers is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Cha++ers.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "src/fe-gtk/gui_main.h"
#include <string.h>
#include <string>
#include <stdlib.h>
#include <pthread.h>
#include "src/libraries/text.h"
#include "src/defined.h"

GtkWidget *view;
GtkWidget *tree_view;
pthread_t pid;

static void WriteToBuffer(const gchar* txt)
{
	GtkTextBuffer *buffer;
	GtkTextIter iterator;
	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
	gtk_text_buffer_get_iter_at_offset(buffer,&iterator,-1);
	gtk_text_view_set_editable (GTK_TEXT_VIEW(view),TRUE);
	gtk_text_buffer_insert(buffer,&iterator,txt,(gint)strlen(txt));
	gtk_text_view_set_editable (GTK_TEXT_VIEW(view),FALSE);
}


static void Event_MenuConnect(GtkWidget* widget, GtkWidget* item)
{
	const char* label = gtk_menu_item_get_label(GTK_MENU_ITEM(item));
	if (strcmp(label,"Connect") == 0) {
		gtk_menu_item_set_label(GTK_MENU_ITEM(item),"Disconnect");

		if (!pid)pthread_create (&pid, NULL, Init_Session, NULL);
	} else {
		gtk_menu_item_set_label(GTK_MENU_ITEM(item),"Connect");
		Disconnect();
		pid = 0;
	}

}

static void Build_Menu(GtkWidget* parent)
{
	GtkWidget* AppMenu = gtk_menu_bar_new();
	GtkWidget* MenuFile = gtk_menu_new();

	/*Network Menu*/
	GtkWidget* ItemFile = gtk_menu_item_new_with_label("Network");
	gtk_menu_bar_append(GTK_MENU_BAR(AppMenu),ItemFile);
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(ItemFile),MenuFile);

	GtkWidget* ItemConnect = gtk_menu_item_new_with_label("Connect");
	gtk_menu_append(GTK_MENU(MenuFile),ItemConnect);
	g_signal_connect (G_OBJECT (ItemConnect), "activate",
	                  G_CALLBACK (Event_MenuConnect), (gpointer)ItemConnect);

	/*Let's show the menu*/
	gtk_box_pack_start (GTK_BOX (parent), AppMenu, FALSE, TRUE, 0);
	gtk_widget_show_all(AppMenu);
}


void TextView_ScrollToBottom()
{
	GtkTextBuffer *buffer = NULL;
	GtkTextMark *mark,*mark_visible;
	GtkTextIter iter_end;
	GtkTextIter iter_visible;

	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
	gtk_text_buffer_get_end_iter(buffer, &iter_end);
	mark = gtk_text_buffer_create_mark(buffer, NULL, &iter_end, FALSE);
	gtk_text_buffer_get_end_iter(buffer, &iter_visible);

	mark_visible = gtk_text_buffer_create_mark(buffer, NULL, &iter_end, FALSE);
	gtk_text_view_move_mark_onscreen(GTK_TEXT_VIEW(view),mark_visible);

	gtk_text_buffer_get_iter_at_mark (buffer,&iter_visible,mark_visible);
	if (gtk_text_iter_get_line(&iter_end)-gtk_text_iter_get_line(&iter_visible) <= 5) {
		gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(view), mark);
	}

	gtk_text_buffer_delete_mark(buffer, mark);
	gtk_text_buffer_delete_mark(buffer, mark_visible);
}

void WriteLine(const gchar* txt)
{
	gchar* ftxt = (gchar*) malloc(8192);
	strcpy(ftxt,txt);
	strcat(ftxt,"\n");
	WriteToBuffer(ftxt);
	if (ftxt != NULL)free(ftxt);

}

void AppendUserlist(std::string uname)
{
	GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
	GtkTreeIter iter;
	gtk_list_store_append (GTK_LIST_STORE (model), &iter);
	gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, uname.c_str(), -1);
}

void ClearUserlist()
{
	GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
	gtk_list_store_clear(GTK_LIST_STORE(model));
}

static GtkWidget *create_list( void )
{

	GtkWidget *scrolled_window;
	GtkListStore *model;
	GtkCellRenderer *cell;
	GtkTreeViewColumn *column;

	/* Create a new scrolled window, with scrollbars only if needed */
	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
	                                GTK_POLICY_AUTOMATIC,
	                                GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),GTK_SHADOW_IN);
	model = gtk_list_store_new (1, G_TYPE_STRING);
	tree_view = gtk_tree_view_new ();
	gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
	gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (model));

	cell = gtk_cell_renderer_text_new ();

	column = gtk_tree_view_column_new_with_attributes ("Users",
	         cell,
	         "text", 0,
	         NULL);

	gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
	                             GTK_TREE_VIEW_COLUMN (column));

	//gtk_widget_set_can_focus(GTK_WIDGET(tree_view),FALSE);
	return scrolled_window;
}

static GtkWidget *create_text( void )
{
	GtkWidget *scrolled_window;
	view = gtk_text_view_new ();
	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
	                                GTK_POLICY_AUTOMATIC,
	                                GTK_POLICY_AUTOMATIC);

	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),GTK_SHADOW_IN);

	gtk_container_add (GTK_CONTAINER (scrolled_window), view);
	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view),GTK_WRAP_WORD_CHAR);
	//gtk_widget_set_can_focus(GTK_WIDGET(view),FALSE);

	return scrolled_window;
}


static void enter_callback( GtkWidget *widget,
                            GtkWidget *entry )
{
	const gchar *entry_text;
	entry_text = gtk_entry_get_text (GTK_ENTRY (entry));
	if (strlen(entry_text) < 1)return;
	SendMessage(entry_text);
	gtk_entry_set_text(GTK_ENTRY(entry),(gchar*)"");
}

static void Build_Interface()
{
	GtkWidget *window;
	GtkWidget *vbox,*hbox;
	GtkWidget *text, *list;
	GtkWidget *entry;

	/* create a new window */
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_default_size (GTK_WINDOW(window),640,480);
	gtk_window_set_title (GTK_WINDOW (window), "Cha++ers");
	g_signal_connect (G_OBJECT (window), "destroy",
	                  G_CALLBACK (gtk_main_quit), NULL);
	g_signal_connect_swapped (G_OBJECT (window), "delete_event",
	                          G_CALLBACK (gtk_widget_destroy),
	                          G_OBJECT (window));

	vbox = gtk_vbox_new (FALSE, 0);
	gtk_container_add (GTK_CONTAINER (window), vbox);

	Build_Menu(vbox);

	hbox = gtk_hpaned_new ();
	gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 2);

	entry = gtk_entry_new ();
	gtk_entry_set_max_length (GTK_ENTRY (entry), 200);
	g_signal_connect (G_OBJECT (entry), "activate",
	                  G_CALLBACK (enter_callback),
	                  (gpointer) entry);

	gtk_entry_set_has_frame(GTK_ENTRY(entry),TRUE);
	gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, TRUE, 2);

	/*Text output control*/
	text = create_text ();
	gtk_paned_add1 (GTK_PANED (hbox), text);
	gtk_text_view_set_editable (GTK_TEXT_VIEW(view),FALSE);

	/*User list control*/
	list = create_list ();
	gtk_paned_add2 (GTK_PANED (hbox), list);

	/*Show all the controls and finish cleaning up*/
	gtk_widget_show_all (window);
	gtk_window_set_focus(GTK_WINDOW(window),entry);
	gtk_paned_set_position(GTK_PANED(hbox),480);
}

static void Cleanup()
{
	Disconnect();
}

int main( int   argc, char *argv[] )
{
	g_thread_init(NULL);
	gdk_threads_init();
	gdk_threads_enter();
	gtk_init (&argc, &argv);

	Build_Interface();

	gtk_main();
	Cleanup();
	gdk_threads_leave();
	return 0;
}
